package kv_table

import (
	"container/list"
	"errors"
	"go-kvsql/bytes_coder"
	"go-kvsql/db/pebbledb"
	"reflect"
	"strconv"
	"strings"
)

type KvTable struct {
	db        *pebbledb.PebbleDB
	tableType reflect.Type
}

func NewKvTable(dbPath string, tableName string, tableType reflect.Type) (*KvTable, error) {
	dbPath = strings.TrimSpace(dbPath)
	if len(dbPath) < 1 {
		return nil, errors.New("kvDbPath is empty.")
	}
	tableName = strings.TrimSpace(tableName)
	if len(tableName) < 1 {
		return nil, errors.New("tableName is empty.")
	}

	db, err := pebbledb.NewDefaultPebbleDB(dbPath + "/" + tableName + "/data")
	if err != nil {
		return nil, err
	}
	kvTable := KvTable{db: db, tableType: tableType}
	return &kvTable, nil
}

func (this *KvTable) Set(key int64, valueBytes []byte) error {
	return this.db.Set([]byte(strconv.FormatInt(key, 10)), valueBytes)
}

func (this *KvTable) Get(key int64) (value interface{}, err error) {
	data, err := this.db.Get([]byte(strconv.FormatInt(key, 10)))
	if err != nil {
		return nil, err
	}
	output := reflect.New(this.tableType).Interface()
	value, err = bytes_coder.DecodeJsonBytes(data, output)
	return
}

func (this *KvTable) Del(key int64) error {
	return this.db.Delete([]byte(strconv.FormatInt(key, 10)))
}

func (this *KvTable) List() *list.List {
	return this.db.List()
}

func (this *KvTable) Table() map[string]string {
	return this.db.Table()
}

func (this *KvTable) Count() int {
	return this.db.Count()
}
